﻿using System;
using System.IO;
using System.ServiceProcess;
using System.Threading;
using DbToPbiSvc.Logging;
using Newtonsoft.Json;

namespace DbToPbiSvc
{
    public partial class Main : ServiceBase
    {

        /// <summary>Used by Threads to stop operations on service stop event.</summary>
        public static bool ServiceIsStopped { get; set; }

        /// <summary>Each query will use own thread.</summary>
        private Thread[] _workerThreads;

        public Main()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {

            try
            {
                LogHelper.TraceDebugInfo("IN");

                ServiceIsStopped = false;

                var queryConfigPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                if (queryConfigPath != null)
                {
                    var jsonContent = File.ReadAllText(Path.Combine(queryConfigPath, "QueryConfig.json"));
                    var queryConfig = JsonConvert.DeserializeObject<QueryConfig>(jsonContent);

                    _workerThreads = new Thread[queryConfig.Queries.Query.Count];

                    LogHelper.TraceDebugInfo(
                        $"Found {queryConfig.Queries.Query.Count.ToString()} queries in QueryConfig.json configuration file.");

                    for (int i = 0; i < queryConfig.Queries.Query.Count; i++)
                    {
                        Worker worker = new Worker();

                        _workerThreads[i] = new Thread(worker.WorkerProcedure);

                        worker.Query = queryConfig.Queries.Query[i];

                        _workerThreads[i].IsBackground = true;
                        _workerThreads[i].Name = queryConfig.Queries.Query[i].Name;
                        _workerThreads[i].Start();
                    }

                }

                LogHelper.TraceDebugInfo("Worker Threads started.");

            }
            catch (Exception exc)
            {
                LogHelper.TraceError(exc);
                throw;
            }
            finally
            {
                LogHelper.TraceDebugInfo("OUT");
            }
        }

        protected override void OnStop()
        {

            try
            {

                LogHelper.TraceDebugInfo("IN");

                ServiceIsStopped = true;

                foreach (var workerThread in _workerThreads)
                {
                    workerThread.Join();
                }

                LogHelper.TraceDebugInfo("Worker Thread stopped.");

            }
            catch (Exception exc)
            {
                LogHelper.TraceError(exc);
            }
            finally
            {
                LogHelper.TraceDebugInfo("OUT");
            }

        }
    }
}
